home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------
- * $Header: /d1/dist/tools/RCS/getopt.c,v 1.1 1991/07/19 14:18:35 carlson Exp $
- *
- * getopt.c My getopt function.
- *
- * Synopsis:
- * getopt [-o <name>] <optstring> <options>
- *
- * Description:
- * Identical to the system 'getopt' command except that it has the
- * additional functions:
- * 1. If the -o option is provided, checks a file called
- * .getopt for a line that begins with <name>. It then
- * uses the options provided on this line as defaults.
- * 2. Normally, the option string contains letters and,
- * optionally, colons to indicate that an option must
- * be followed by an argument. In addition, we allow
- * a '=' to indicate that an option might be followed
- * immediately by an argument (with no white space),
- * a '+' to indicate that an option might be followed
- * by an argument (with white space).
- *
- * Revision history:
- * $Log: getopt.c,v $
- * Revision 1.1 1991/07/19 14:18:35 carlson
- * Initial revision
- *
- *-----------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <errno.h>
- #include <ctype.h>
- #include <string.h>
-
- char opt_name[50], opt_string[50], flg_string[50];
- char buffer[256], *t_argv[50];
-
- char act_opts[50], act_flgs[50], *act_args[50], *rem_args[50];
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- register int i, cur_opt;
- register char *cp;
-
- if (argc < 3) {
- fprintf (stderr, "Usage: %s [-o <name>] <optstring> <options>\n",
- argv[0]);
- fprintf (stderr,
- " <name> = Name found in file .getopt to provide\n");
- fprintf (stderr,
- " default options.\n");
- fprintf (stderr,
- " <optstring> = Option characters to allow. The\n");
- fprintf (stderr,
- " following additional characters mean:\n");
- fprintf (stderr,
- " : - Required argument follows.\n");
- fprintf (stderr,
- " = - Optional argument follows with no\n");
- fprintf (stderr,
- " white space.\n");
- fprintf (stderr,
- " + - Optional argument follows.\n");
- exit (0);
- }
-
- /*----
- * If the option -o is provided, search through the file .getopt (if it
- * exists) for a line that is equal to argv[2].
- *
- * If there is a line that matches argv[2], build an array similar to
- * argv with the options found.
- *----*/
-
- cur_opt = 1;
- if (strcmp (argv[1], "-o") == 0) {
- FILE *fp;
-
- if ((fp = fopen (".getopt", "r")) != NULL) {
- while (fgets (buffer, sizeof (buffer), fp)) {
- cp = strtok (buffer, " \t");
- if (strcmp (cp, argv[2]) == 0)
- break;
- }
-
- if (cp) {
- for (i = 0; (cp = strtok (NULL, " \t")); i++)
- t_argv[i] = cp;
- t_argv[i] = NULL;
-
- do_opts (t_argv, 0, i);
- }
-
- fclose (fp);
- }
-
- cur_opt = 3;
- }
-
- for (cp = argv[cur_opt++], i = 0; *cp; cp++, i++) {
- opt_string[i] = *cp;
- flg_string[i] = (*(cp+1) && strchr (":+=", *(cp+1))) ? *(++cp) : '\0';
- }
- opt_string[i] = '\0';
-
- do_opts (argv, cur_opt, argc);
-
- for (i = 0; act_opts[i]; i++) {
- putchar ('-');
- putchar (act_opts[i]);
- putchar (' ');
- if (act_args[i]) {
- fputs (act_args[i], stdout);
- putchar (' ');
- }
- }
-
- putchar ('-');
- putchar ('-');
-
- for (i = 0; rem_args[i]; i++) {
- putchar (' ');
- fputs (rem_args[i], stdout);
- }
-
- putchar ('\n');
- }
-
- do_opts (argv, first, last)
- char *argv[];
- int first, last;
- {
- register int i, j, k, l;
- register char *cp;
-
- /*----
- * Loop through arguments and check each if it is an expected
- * option.
- *
- * i = index into argv.
- * j = misc.
- * k = index into act_opts.
- * l = index into character position of current argv[i].
- *----*/
-
- for (i = first, k = 0; i < last; i++) {
- if (argv[i][0] == '-') {
- if (argv[i][1] == '-') {
- i++;
- break;
- }
- for (l = 1; argv[i][l]; ) {
- if ((cp = strchr (opt_string, argv[i][l]))) {
- act_opts[k] = argv[i][l];
- act_args[k] = NULL;
- j = cp - opt_string;
- switch (flg_string[j]) {
- case ':': /* Must be an argument */
- if (argv[i][++l]) {
- act_args[k] = &argv[i][l];
- } else {
- if (++i >= last) {
- act_args[k] = "NOARG";
- } else {
- act_args[k] = argv[i];
- }
- }
- l = strlen (argv[i]);
- k++;
- break;
-
- case '=': /* There may be an immediate arg */
- if (argv[i][++l]) {
- act_args[k] = &argv[i][l];
- l = strlen (argv[i]);
- }
- k++;
- break;
-
- case '+': /* Thare may be an arg */
- if (!argv[i][++l] && (argv[i+1][0] != '-')) {
- act_args[k] = argv[++i];
- l = strlen (argv[i]);
- }
- k++;
- break;
-
- default:
- l++;
- k++;
- }
- } else { /* Not recognized option */
- fprintf (stderr, "Unrecognized option: %c\n",
- argv[i][l++]);
- }
- }
- } else {
- break;
- }
- }
-
- act_opts[k] = '\0';
-
- for (k = 0; i < last; i++, k++) {
- rem_args[k] = argv[i];
- }
- rem_args[k] = NULL;
- }
-